<?php

namespace app\api\controller\xykeep;
use app\common\controller\Api;
use think\Db;
use think\Exception;
use think\Log;
use app\api\model\xykeep\User;
use \addons\xykeep\service\PayService;
use app\api\model\xykeep\present\Order as PresentOrderModel;
use app\api\model\xykeep\vip\Order as VipOrderModel;
use app\api\model\xykeep\course\Order as CourseOrderModel;
use app\api\model\xykeep\goods\Order as GoodsOrderModel;
use app\api\model\xykeep\recharge\Order as RechargeOrderModel;
use app\api\model\xykeep\facial\Order as FacialOrderModel;
use app\api\model\xykeep\Third;

class Pay extends Api
{

    protected $noNeedLogin = ['prepay', 'notifyx'];
    protected $noNeedRight = ['*'];


    /**
     * 拉起支付
     */
    public function prepay()
    {
        xykeepCheckEnv('yansongda');

        $user = User::info();
        $order_sn = $this->request->post('order_sn');
        $payment = $this->request->post('payment');
        $order_type = $this->request->post('order_type');
        $platform = request()->header('platform');

        list($order, $title) = $this->getOrderInstance($order_type);
        $order = $order->where(['order_sn'=> $order_sn,'user_id'=>$user->id])->find();

//        $this->error("主动报错，强制进入重新支付状态");
        if (!$order) {
            $this->error("订单不存在");
        }

        if (in_array($order->status, [-2,-1])) {
            $this->error("订单已失效");
        }

        try{
            Db::startTrans();
            if($order['total_fee']==0){
                $notify = [
                    'order_sn' => $order['order_sn'],
                    'transaction_id' => '',
                    'notify_time' => date('Y-m-d H:i:s'),
                    'buyer_email' => $user->id,
                    'pay_fee' => $order->total_fee,
                    'pay_type' => $payment
                ];
                $notify['payment_json'] = json_encode($notify);
                $result = $order->paySuccess($order, $notify);
            }elseif($payment == 'balance'){
                // 余额支付
                $result = $this->balancePay($order,$order_type);
            }elseif ($payment == 'wechat') {
                $order_data = [
                    'order_id' => $order->id,
                    'out_trade_no' => $order->order_sn,
                    'total_fee' => $order->total_fee,
                ];
                if (in_array($platform, ['wxMiniProgram','wxOfficialAccount'])) {
                    if (isset($openid) && $openid) {
                        $order_data['openid'] = $openid;
                    } else {
                        $third = Third::where([
                            'user_id' => $order->user_id,
                            'platform' => $platform
                        ])->find();

                        $order_data['openid'] = $third ? $third->openid : '';
                    }
                }
                $order_data['body'] = $title;

                if (in_array($platform, ['wxMiniProgram','wxOfficialAccount'])) {
                    if (isset($openid) && $openid) {
                        $order_data['openid'] = $openid;
                    } else {
                        $third = Third::where([
                            'user_id' => $order->user_id,
                            'platform' => $platform
                        ])->find();

                        $order_data['openid'] = $third ? $third->openid : '';
                    }
                }
                $order_data['body'] = $title;

                $notify_url = $this->request->root(true) . '/api/xykeep/pay/notifyx/payment/' . $payment . '/platform/' . $platform .'/order_type/'.$order_type;
                $pay = new PayService($payment, $platform, $notify_url);
                $result = $pay->create($order_data);

            }else{
                throw new \Exception('支付方式错误');
            }
            Db::commit();

        } catch (\Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }

        $this->success('获取预付款成功', [
            'pay_data' => $result,
        ]);


    }

    /**
     * 支付成功回调
     */
    public function notifyx()
    {

        $payment = $this->request->param('payment');
        $platform = $this->request->param('platform');
        $order_type = $this->request->param('order_type');

        $pay = new PayService($payment, $platform);

        $result = $pay->notify(function ($data, $pay = null) use ($payment,$order_type) {

            try {
                $out_trade_no = $data['out_trade_no'];

                list($order, $title) = $this->getOrderInstance($order_type);


                if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) {
                    // 微信交易未成功，返回 false，让微信再次通知
                    return false;
                }

                // 支付成功流程
                $pay_fee = $data['total_fee'] / 100;

                $order = $order->where('order_sn', $out_trade_no)->find();

                if (!$order || $order->status > 0) {
                    // 订单不存在，或者订单已支付
                    return $pay->success()->send();
                }

                Db::transaction(function () use ($order, $data, $payment, $pay_fee) {
                    $notify = [
                        'order_sn' => $data['out_trade_no'],
                        'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'],
                        'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'] ?? $data['notify_time'])),
                        'payment_json' => json_encode($data),
                        'pay_fee' => $pay_fee,
                        'pay_type' => $payment
                    ];

                    $order->paySuccess($order, $notify);

                });

                return $pay->success()->send();
            } catch (\Exception $e) {
                Log::write('notifyx-error:' . json_encode($e->getMessage()));
            }
        });

        return $result;
    }

    // 余额支付
    private function balancePay ($order,$order_type) {

        if (!$order) {
            throw new \Exception('订单已支付');
        }
        $total_fee = $order->total_fee;

        $user = User::info();

        if (is_null($user)) {
            throw new \Exception(__('Please login first'));
        }

        if($user->money < $total_fee){
            throw new \Exception('积分不足');
        }

        $user_id = $user->id;
        $remark = '';

        User::money(-$total_fee, $user_id, 'pay_'.$order_type, $remark,$order->id);


        $notify = [
            'order_sn' => $order['order_sn'],
            'transaction_id' => '',
            'notify_time' => date('Y-m-d H:i:s'),
            'buyer_email' => $user->id,
            'pay_fee' => $order->total_fee,
            'pay_type' => 'balance'
        ];
        $notify['payment_json'] = json_encode($notify);
        $order->paySuccess($order, $notify);

        return $order;
    }

    /**
     * 根据订单类型获取订单实例
     */
    public static function getOrderInstance($order_type)
    {
        $order = null;
        $title = '订单';

        // 课程订单
        if ($order_type == 'course') {
            $order = new CourseOrderModel();
            $title = '课程'.$title;
        }

        // 商城订单
        if($order_type == 'goods'){
            $order = new GoodsOrderModel();
            $title = '商城'.$title;
        }

        // 充值订单
        if ($order_type == 'recharge') {
            $order = new RechargeOrderModel();
            $title = '充值'.$title;
        }

        // 权益卡订单
        if ($order_type == 'card') {
            $order = new \app\common\model\CardOrder();
            $title = '权益卡'.$title;
        }

        return [$order,$title];
    }

}
